package com.UnionPayCenter.service.serviceImpl;

import com.UnionPayCenter.account.manager.ChargeBillManager;
import com.UnionPayCenter.entity.CouponEntity;
import com.UnionPayCenter.entity.MpIndexPageEntity;
import com.UnionPayCenter.entity.MpMessageLogEntity;
import com.UnionPayCenter.entity.ShopCardInfoEntity;
import com.UnionPayCenter.entity.ShopEntity;
import com.UnionPayCenter.entity.ShopInfoEntity;
import com.UnionPayCenter.entity.UserEntity;
import com.UnionPayCenter.entity.vo.UserVo;
import com.UnionPayCenter.enums.ErrorCodeEnum;
import com.UnionPayCenter.exception.ApiException;
import com.UnionPayCenter.mapper.MpIndexPageMapper;
import com.UnionPayCenter.mapper.MpMessageLogMapper;
import com.UnionPayCenter.mapper.ShopCardInfoMapper;
import com.UnionPayCenter.mapper.ShopInfoMapper;
import com.UnionPayCenter.mapper.ShopMapper;
import com.UnionPayCenter.mapper.UserMapper;
import com.UnionPayCenter.message.resp.TextMessage;
import com.UnionPayCenter.operation.entity.request.MpPushRequest;
import com.UnionPayCenter.operation.entity.request.MpPushToAllRequest;
import com.UnionPayCenter.redis.IRedisService;
import com.UnionPayCenter.service.IShopService;
import com.UnionPayCenter.service.IUserService;
import com.UnionPayCenter.service.IWechatService;
import com.UnionPayCenter.sms.StringUtil;
import com.UnionPayCenter.util.DateFormatUtil;
import com.UnionPayCenter.util.MessageUtil;
import com.UnionPayCenter.util.StringUtils;
import com.UnionPayCenter.vastchain.WechatPayUtil;
import com.UnionPayCenter.wechat.ComponentUtil;
import com.UnionPayCenter.wechat.WXCardSignatureUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Slf4j
@Service
@Transactional
public class WechatServiceImpl implements IWechatService {
    @Autowired
    private IUserService userService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private ShopInfoMapper shopInfoMapper;

    @Autowired
    private ShopCardInfoMapper shopCardInfoMapper;

    @Autowired
    private MpIndexPageMapper mpIndexPageMapper;

    @Autowired
    private MpMessageLogMapper mpMessageLogMapper;

    @Autowired
    private IShopService shopService;

    @Autowired
    private IRedisService redisService;

    @Autowired
    private ChargeBillManager chargeBillService;


    @Override
    public String mpBack(HttpServletRequest request, HttpServletResponse response) {
        String respMessage = "success";
        try {
            // xml请求解析
            Map<String, String> map = MessageUtil.parseXml(request);

            if (map != null) {
                log.info("XML报文内容为：" + map);

                String toUserName = map.get("ToUserName");//开发者微信号。
                String fromUserName = map.get("FromUserName");//领券方帐号（一个OpenID）。

                String msgType = map.get("MsgType");//消息类型
                if (MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {
                    String event = map.get("Event");//事件类型
                    //卡券领取事件推送 user_get_card(用户领取卡券)。
                    if (event.equals(MessageUtil.EVENT_TYPE_USER_GET_CARD)) {
                        /**
                         IsGiveByFriend	是否为转赠领取，1代表是，0代表否。
                         FriendUserName	当IsGiveByFriend为1时填入的字段，表示发起转赠用户的openid
                         OldUserCardCode	为保证安全，微信会在转赠发生后变更该卡券的code号，该字段表示转赠前的code。
                         OuterStr	领取场景值，用于领取渠道数据统计。可在生成二维码接口及添加Addcard接口中自定义该字段的字符串值。
                         IsRestoreMemberCard	用户删除会员卡后可重新找回，当用户本次操作为找回时，该值为1，否则为0
                         CreateTime 消息创建时间 （整型）。
                         */
                        try {
                            String userCardCode = map.get("UserCardCode");//code序列号。
                            String unionId = map.get("UnionId");//领券用户的UnionId。
                            String cardId = map.get("CardId"); //卡券ID。

                            ShopInfoEntity shopInfo = shopService.getByCardId(cardId);
                            if (shopInfo == null) {
                                return respMessage;
                            }
                            ShopEntity shop = shopMapper.selectByPrimaryKey(shopInfo.getShopId());
                            if (shop == null) {
                                return respMessage;
                            }

                            UserVo vo = userService.getByUnionid(unionId, shopInfo.getShopId());
                            if (vo == null) {
                                return respMessage;
                            } else {
                                vo.setWxOpenid(fromUserName);
                                vo.setWxCard(userCardCode);
                                // 保存公众号openid
                                UserEntity user = new UserEntity();
                                user.setUserId(vo.getUserId());
                                user.setWxOpenid(fromUserName);
                                user.setWxCard(userCardCode);
                                userMapper.updateByPrimaryKeySelective(user);
                            }

                            //发送模版消息
                            return this.sendCardMsg(vo, shop, shopInfo) ? "" : null;
                        } catch (Exception e) {
                            return respMessage;
                        }
                    } else if (event.equals(MessageUtil.EVENT_TYPE_USER_VIEW_CARD)) {
                        String userCardCode = map.get("UserCardCode");//code序列号。
                        String unionId = map.get("UnionId");//领券用户的UnionId。
                        String cardId = map.get("CardId"); //卡券ID。

                        try {
                            ShopInfoEntity shopInfo = shopService.getByCardId(cardId);
                            if (shopInfo == null) {
                                return respMessage;
                            }
                            UserVo vo = userService.getByUnionid(unionId, shopInfo.getShopId());
                            if (vo == null) {
                                return respMessage;
                            } else {
                                if (StringUtils.isNullStr(vo.getWxOpenid())) {
                                    // 保存公众号openid
                                    UserEntity user = new UserEntity();
                                    user.setUserId(vo.getUserId());
                                    user.setWxOpenid(fromUserName);
                                    user.setWxCard(userCardCode);
                                    userMapper.updateByPrimaryKeySelective(user);
                                }
                            }

                            return "";
                        } catch (Exception e) {
                            return respMessage;
                        }
                    } else if (event.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                        String respContent = "你好，感谢关注！";
                        //回复文本消息
                        TextMessage textMessage = new TextMessage();
                        textMessage.setToUserName(fromUserName);
                        textMessage.setFromUserName(toUserName);
                        textMessage.setCreateTime(new Date().getTime());
                        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
                        textMessage.setContent(respContent);
                        respMessage = MessageUtil.textMessageToXml(textMessage);
                    }

                }
            }
        } catch (Exception e) {
            log.error("mpBack 处理失败", e);
        }
        return respMessage;
    }

    @Override
    public boolean sendCardMsg(UserVo user, ShopEntity shop, ShopInfoEntity shopInfo) {
        return sendXcxCardMsg(user, shop, shopInfo);
    }

    /**
     * @Description: 发送微信公众号模版消息
     * @Param:
     * @return:
     * @Author: bite
     * @Date: 2019/6/17
     */
    public boolean sendWxCardMsg(UserVo user, ShopEntity shop, ShopInfoEntity shopInfo) {
        //模版消息id
        String modelId = "zeG75M25MAz7Rr_tqsCZ_cqS4xwDDwXtLLx3ePES8rM";
        JSONObject json = new JSONObject();
        try {
            //TODO 跳转路径
            String url = "";
            json.put("touser", user.getWxOpenid());
            json.put("template_id", modelId);
            json.put("url", url);
            json.put("topcolor", "#0000EE");

            //跳转微信小程序需要
//            if(shopInfo.getAppId() != null) {
//                JSONObject miniprogram = new JSONObject();
//                miniprogram.put("appid", shopInfo.getAppId());
//                //所需跳转到小程序的具体页面路径，支持带参数
////                miniprogram.put("pagepath", "");
//                json.put("miniprogram", miniprogram);
//            }

            JSONObject ja = new JSONObject();

            //first.DATA
            JSONObject ja1 = new JSONObject();
            ja1.put("value", "您已成功领取会员卡！");
            ja1.put("color", "#173177");
            ja.put("first", ja1);

            //keyword1.DATA
            ja1 = new JSONObject();
            ja1.put("value", shop.getShopName());
            ja1.put("color", "#173177");
            ja.put("keyword1", ja1);

            //keyword2.DATA
            ja1 = new JSONObject();
            ja1.put("value", user.getMobile());
            ja1.put("color", "#173177");
            ja.put("keyword2", ja1);

            //keyword3.DATA
            ja1 = new JSONObject();
            ja1.put("value", user.getWxCard() == null ? user.getCard() : user.getWxCard());
            ja1.put("color", "#173177");
            ja.put("keyword3", ja1);

            //keyword4.DATA
            ja1 = new JSONObject();
            ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(user.getBalance()) / 100)) + "元");
            ja1.put("color", "#173177");
            ja.put("keyword4", ja1);

            //remark.DATA
            ja1 = new JSONObject();
            ja1.put("value", "进入【我】-【卡包】查看已领卡券");
            ja1.put("color", "#173177");
            ja.put("remark", ja1);

            json.put("data", ja);

            return WXCardSignatureUtil.templateSend(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * @Description: 发送小程序模版消息
     * @Param:
     * @return:
     * @Author: bite
     * @Date: 2019/6/17
     */
    public boolean sendXcxCardMsg(UserVo user, ShopEntity shop, ShopInfoEntity shopInfo) {
        //模版消息id
//        String modelId = "9aikmDkTzZlxXmTjBghu0Afiky6jWsrhiGa5OgO0a3I";
        JSONObject json = new JSONObject();
        String modelId = shopInfo.getCardTemplateId();
        if (StringUtils.isNullStr(modelId)) {
            return false;
        }
        String formid = this.getFormid(user.getUserId());
        if (StringUtils.isNullStr(formid)) {
            return false;
        }
        // 跳转路径
        String page = "pages/user/index";
        json.put("touser", user.getOpenid());
        json.put("template_id", modelId);
        json.put("page", page);
        json.put("form_id", formid);

        JSONObject ja = new JSONObject();

        //keyword1.DATA
        JSONObject ja1 = new JSONObject();
        ja1.put("value", user.getWxCard() == null ? user.getCard() : user.getWxCard());
        ja.put("keyword1", ja1);

        //keyword2.DATA
        ja1 = new JSONObject();
        ja1.put("value", "会员卡");
        ja.put("keyword2", ja1);

        //keyword3.DATA
        ja1 = new JSONObject();
        ja1.put("value", user.getUserLevelName());
        ja.put("keyword3", ja1);

        //keyword4.DATA
        ja1 = new JSONObject();
        ja1.put("value", DateFormatUtil.Now());
        ja.put("keyword4", ja1);

        json.put("data", ja);

        return pushMpMessage(shopInfo, json.toString());
    }

    @Override
    public boolean sendDepositMsg(UserEntity user, String amount, String time, String balance, String sn, Integer shopId) {
        return sendXcxDepositMsg(user, amount, time, balance, sn, shopId);
    }

    public boolean sendWxDepositMsg(UserEntity user, String amount, String time, String balance, Integer shopId) {

        //模版消息id
        String modelId = "JBRQ1xN3fo7cVhuEMRqLhOtiTbNx13dhN5l0yBYGEK8";
        JSONObject json = new JSONObject();
        try {
            if (StringUtils.isNullStr(user.getWxOpenid())) {
                return false;
            }
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return false;
            }

            json.put("touser", user.getWxOpenid());
            json.put("template_id", modelId);
            json.put("topcolor", "#0000EE");

            JSONObject ja = new JSONObject();

            //first.DATA
            JSONObject ja1 = new JSONObject();
            ja1.put("value", "恭喜您，充值成功！");
            ja1.put("color", "#173177");
            ja.put("first", ja1);

            //keyword1.DATA
            ja1 = new JSONObject();
            ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(amount) / 100)) + "元");
            ja1.put("color", "#173177");
            ja.put("keyword1", ja1);

            //keyword2.DATA
            ja1 = new JSONObject();
            ja1.put("value", time);
            ja1.put("color", "#173177");
            ja.put("keyword2", ja1);

            //keyword3.DATA
            ja1 = new JSONObject();
            ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(balance) / 100)) + "元");
            ja1.put("color", "#173177");
            ja.put("keyword3", ja1);

            //remark.DATA
            ja1 = new JSONObject();
            ja1.put("value", "谢谢您的惠顾");
            ja1.put("color", "#173177");
            ja.put("remark", ja1);

            json.put("data", ja);

            return WXCardSignatureUtil.templateSend(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    public boolean sendXcxDepositMsg(UserEntity user, String amount, String time, String balance, String sn, Integer shopId) {
        //模版消息id
//        String modelId = "kVctDKN2DtXoT_eZr3Ov4N8DaYFmiNBKR-z2RYwG84I";
        JSONObject json = new JSONObject();
        ShopEntity shop = shopMapper.selectByPrimaryKey(shopId);
        ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
        if (shop == null || shopInfo == null) {
            return false;
        }
        String modelId = shopInfo.getDepositTemplateId();
        if (StringUtils.isNullStr(modelId)) {
            return false;
        }
        String formid = this.getFormid(user.getUserId());
        if (StringUtils.isNullStr(formid)) {
            return false;
        }
        //跳转路径
        String page = "pages/user/index";
        json.put("touser", user.getOpenid());
        json.put("template_id", modelId);
        json.put("page", page);
        json.put("form_id", formid);

        JSONObject ja = new JSONObject();

        //keyword1.DATA
        JSONObject ja1 = new JSONObject();
        ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(amount) / 100)) + "元");
        ja.put("keyword1", ja1);

        //keyword2.DATA
        ja1 = new JSONObject();
        ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(balance) / 100)) + "元");
        ja.put("keyword2", ja1);

        //keyword3.DATA
        ja1 = new JSONObject();
        ja1.put("value", shop.getShopName());
        ja.put("keyword3", ja1);

        //keyword4.DATA
        ja1 = new JSONObject();
        ja1.put("value", time);
        ja.put("keyword4", ja1);

        //keyword5.DATA
        ja1 = new JSONObject();
        ja1.put("value", sn);
        ja.put("keyword5", ja1);

        json.put("data", ja);

        return pushMpMessage(shopInfo, json.toString());
    }

    @Override
    public boolean sendPayMsg(UserEntity user, String sn, String time, String amount, String balance, String type, Integer shopId) {
        return sendXcxPayMsg(user, sn, time, amount, balance, type, shopId);
    }

    @Override
    public boolean pushMpMsg(MpPushRequest mpPushRequest) {
        Integer shopId = mpPushRequest.getShopId();
        // 如果前端没有传userid, 默认推送到所有账户
        List<Integer> userIds = mpPushRequest.getUserIds();
        List<UserEntity> users = null;
        if (CollectionUtils.isEmpty(userIds)) {
            users = userService.getUserByShopId(shopId);
        } else {
            users = userService.getUserById(mpPushRequest.getUserIds());
        }
        if (CollectionUtils.isEmpty(users)) {
            log.warn("no users belongs to shop, shop id {}", shopId);
            return true;
        }

        return pushMsg(mpPushRequest, users);

    }

    @Override
    public boolean pushMpMsgToAll(MpPushToAllRequest mpPushRequest) {
        List<UserVo> userVos = userMapper.selectList(mpPushRequest.getShopId(), mpPushRequest.getMobile(), mpPushRequest.getStartTime(),
                mpPushRequest.getEndTime(), mpPushRequest.getUserLevel(), null, null,
                mpPushRequest.getStartTotalAmount(), mpPushRequest.getEndTotalAmount());
        if (CollectionUtils.isEmpty(userVos)) {
            return true;
        }
        return pushMsg(mpPushRequest, userVos);
    }

    @Override
    public boolean pushCouponsNotify(Integer shopId, Integer userId, CouponEntity couponEntity, String endTime, Integer quantity) {
        ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
        if (shopInfo == null) {
            log.warn("push mp message, shop is not exist, shopId {}", shopId);
            throw new ApiException(ErrorCodeEnum.CP6002.code(), String.format(ErrorCodeEnum.CP6002.msg(), "店铺"));
        }
        String templateId = getCouponsNotifyTemplateId(shopInfo, "AT0551");
        String formid = this.getFormid(userId);
        if (StringUtils.isNullStr(formid)) {
            log.info("user formid not exist {}", userId);
            return false;
        }
        // 跳转路径
        UserEntity user = userService.getUserById(userId);
        JSONObject json = new JSONObject();
        json.put("touser", user.getOpenid());
        json.put("template_id", templateId);
        json.put("page", "pages/user/index?redirect=pages/mycoupons/index");
        json.put("form_id", formid);

        JSONObject ja = new JSONObject();

        //keyword1.DATA
        JSONObject ja1 = new JSONObject();
        ja1.put("value", couponEntity.getDisName() + "(" + quantity + "张)");
        ja.put("keyword1", ja1);

        JSONObject ja2 = new JSONObject();
        ja2.put("value", DateFormatUtil.dateToString(new Date()));
        ja.put("keyword2", ja2);

        JSONObject ja3 = new JSONObject();
        if (!StringUtil.isNullOrEmpty(endTime) && endTime.contains("204")) {
            endTime = "永久有效";
        }
        ja3.put("value", endTime);
        ja.put("keyword3", ja3);

        json.put("data", ja);

        return pushMpMessage(shopInfo, json.toString());
    }

    private boolean pushMsg(MpPushRequest mpPushRequest, List<? extends UserEntity> users) {
        Integer shopId = mpPushRequest.getShopId();
        ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
        if (shopInfo == null) {
            log.warn("push mp message, shop is not exist, shopId {}", shopId);
            throw new ApiException(ErrorCodeEnum.CP6002.code(), String.format(ErrorCodeEnum.CP6002.msg(), "店铺"));
        }
        String templateId = getMpMessageTemplateId(shopInfo, "AT0480");

        MpIndexPageEntity mpIndexPageEntity = mpIndexPageMapper.selectById(mpPushRequest.getIndexPageId());

        for (UserEntity user : users) {
            String formid = this.getFormid(user.getUserId());
            if (StringUtils.isNullStr(formid)) {
                log.info("user formid not exist {}", user.getUserId());
                continue;
            }
            // 跳转路径
            JSONObject json = new JSONObject();
            json.put("touser", user.getOpenid());
            json.put("template_id", templateId);
            json.put("page", mpIndexPageEntity.getUrl());
            json.put("form_id", formid);

            JSONObject ja = new JSONObject();

            //keyword1.DATA
            JSONObject ja1 = new JSONObject();
            ja1.put("value", DateFormatUtil.dateToString(new Date()));
            ja.put("keyword1", ja1);

            JSONObject ja2 = new JSONObject();
            ja2.put("value", mpPushRequest.getMessage());
            ja.put("keyword2", ja2);

            json.put("data", ja);

            return pushMpMessage(shopInfo, json.toString());

        }
        return true;
    }

    @Override
    public com.alibaba.fastjson.JSONObject pay(Integer userId, Integer shopId, int amount, String sn) {
        //微信支付
        ShopInfoEntity shopInfo = shopService.wechatPayGetShopInfo(shopId);
        UserEntity user = userService.wechatPayGetUser(userId);
        try {
            com.alibaba.fastjson.JSONObject json = WechatPayUtil.pay(shopInfo, user, "", amount, "支付");
            String prepayId = json.getString("prepayId");
            //修改第三方流水号
            chargeBillService.updateThirdSn(sn, prepayId);
            //返回前端唤起支付信息
            return json.getJSONObject("return");
        } catch (ApiException e) {
            log.error(String.format("微信支付 WechatPayUtil.pay 调取失败"), e);
            throw new ApiException(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("微信支付 WechatPayUtil.pay 调取失败2"), e);
            throw new ApiException(ErrorCodeEnum.WP8007);
        }
    }

    @Override
    public com.alibaba.fastjson.JSONObject unionPay(Integer userId, Integer shopId, int amount, String sn) {
        //银联支付
        ShopInfoEntity shopInfo = shopService.wechatPayGetShopInfo(shopId);
        UserEntity user = userService.wechatPayGetUser(userId);
        try {
            com.alibaba.fastjson.JSONObject json = WechatPayUtil.unionPay(shopInfo, user, "", amount, "支付");
            String prepayId = json.getString("prepayId");
            //修改第三方流水号
            chargeBillService.updateThirdSn(sn, prepayId);
            //返回前端唤起支付信息
            return json.getJSONObject("return");
        } catch (ApiException e) {
            log.error(String.format("银联支付 WechatPayUtil.unionPay 调取失败"), e);
            throw new ApiException(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("银联支付 WechatPayUtil.unionPay 调取失败2"), e);
            throw new ApiException(ErrorCodeEnum.WP8007);
        }
    }

    public boolean sendWxPayMsg(UserEntity user, String sn, String time, String amount, String type, Integer shopId) {
        //模版消息id
        String modelId = "oziXRhIgU_001eD42nS0sUUC2R0b6ta2DmrW1KXe3kw";
        JSONObject json = new JSONObject();
        try {
            if (StringUtils.isNullStr(user.getWxOpenid())) {
                return false;
            }
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return false;
            }

            json.put("touser", user.getWxOpenid());
            json.put("template_id", modelId);
            json.put("topcolor", "#0000EE");

            JSONObject ja = new JSONObject();

            //first.DATA
            JSONObject ja1 = new JSONObject();
            ja1.put("value", "您好，您的订单已支付成功！");
            ja1.put("color", "#173177");
            ja.put("first", ja1);

            //keyword1.DATA
            ja1 = new JSONObject();
            ja1.put("value", sn);
            ja1.put("color", "#173177");
            ja.put("keyword1", ja1);

            //keyword2.DATA
            ja1 = new JSONObject();
            ja1.put("value", time);
            ja1.put("color", "#173177");
            ja.put("keyword2", ja1);

            //keyword3.DATA
            ja1 = new JSONObject();
            ja1.put("value", String.valueOf(BigDecimal.valueOf(Double.valueOf(amount) / 100)) + "元");
            ja1.put("color", "#173177");
            ja.put("keyword3", ja1);

            //keyword4.DATA
            ja1 = new JSONObject();
            ja1.put("value", type);
            ja1.put("color", "#173177");
            ja.put("keyword4", ja1);

            //remark.DATA
            ja1 = new JSONObject();
            ja1.put("value", "感谢您的惠顾");
            ja1.put("color", "#173177");
            ja.put("remark", ja1);

            json.put("data", ja);

            return WXCardSignatureUtil.templateSend(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    public boolean sendXcxPayMsg(UserEntity user, String sn, String time, String amount, String balance, String type, Integer shopId) {
        //模版消息id
//        String modelId = "Ld__4kV5iOQRA8AXJi4kgQfm4WoURtW25Ifc1HOxdB4";
        JSONObject json = new JSONObject();
        ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
        if (shopInfo == null) {
            return false;
        }
        String modelId = shopInfo.getPayTemplateId();
        if (StringUtils.isNullStr(modelId)) {
            modelId = getBalanceChangeNotifyTemplateId(shopInfo, "AT0157");
            //String templateId = ComponentUtil.getTemplate(shopInfo.getAppId(), "AT0157");
        }
        String formid = this.getFormid(user.getUserId());
        if (StringUtils.isNullStr(formid)) {
            return false;
        }
        // 跳转路径
        String page = "pages/user/index?redirect=pages/balance/index";
        json.put("touser", user.getOpenid());
        json.put("template_id", modelId);
        json.put("page", page);
        json.put("form_id", formid);

        JSONObject ja = new JSONObject();

        //keyword1.DATA
        JSONObject ja1 = new JSONObject();
        ja1.put("value", BigDecimal.valueOf(Double.valueOf(balance) / 100) + "元");
        ja.put("keyword1", ja1);

        JSONObject ja2 = new JSONObject();
        ja2.put("value", "-" + BigDecimal.valueOf(Double.valueOf(amount) / 100) + "元");
        ja.put("keyword2", ja2);

        //keyword2.DATA
        JSONObject ja3 = new JSONObject();
        ja3.put("value", "消费支出");
        ja.put("keyword3", ja3);

        //keyword3.DATA
        JSONObject ja4 = new JSONObject();
        ja4.put("value", time);
        ja.put("keyword4", ja4);

        json.put("data", ja);

        return pushMpMessage(shopInfo, json.toString());
    }

    @Override
    public String getFormid(Integer userId) {
        return getFormid(userId, true);
    }

    @Override
    public String getFormid(Integer userId, boolean delete) {
        Set<String> keys = redisService.keys("formId:" + userId + ":");
        if (keys != null && keys.size() != 0) {
            String key = keys.iterator().next();
            String formid = redisService.getString(key);
            if (delete) {
                redisService.deleteString(key);
            }
            return formid;
        }
        return null;
    }

    @Override
    public String createCard(Integer shopId, Integer infoId) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return null;
            }
            ShopCardInfoEntity cardInfo = shopCardInfoMapper.selectByPrimaryKey(infoId);
            if (cardInfo == null) {
                return null;
            }
            JSONObject baseInfo = new JSONObject();
            //"logo_url" 是	卡券的商户logo
            baseInfo.put("logo_url", cardInfo.getLogoUrl());
            //"brand_name" 	是 商户名字,字数上限为12个汉字。
            baseInfo.put("brand_name", cardInfo.getBrandName());
            //"code_type" 是 	Code展示类型
            baseInfo.put("code_type", cardInfo.getCodeType());
            //"title" 是 卡券名，字数上限为9个汉字 (建议涵盖卡券属性、服务及金额)。
            baseInfo.put("title", cardInfo.getTitle());
            //"color" 是	 	券颜色。按色彩规范标注填写Color010-Color100
            baseInfo.put("color", cardInfo.getColor());
            //"notice" 	是	卡券使用提醒，字数上限为16个汉字。
            baseInfo.put("notice", cardInfo.getNotice());
            //"description"  是 	卡券使用说明，字数上限为1024个汉字。
            baseInfo.put("description", cardInfo.getDescription());
            //"date_info": { 是	JSON	使用日期，有效期的信息。
            //    "type": "DATE_TYPE_PERMANENT" 是 使用时间的类型 支持固定时长有效类型 固定日期有效类型 永久有效类型( DATE_TYPE_PERMANENT)
            //},
            baseInfo.put("date_info", new JSONObject().put("type", "DATE_TYPE_PERMANENT"));
            //"sku": { 	是	JSON  商品信息。
            //    "quantity"  是		卡券库存的数量上限为100000000
            //},
            baseInfo.put("sku", new JSONObject().put("quantity", 80000000));
            //"get_limit" 否 每人可领券的数量限制，建议会员卡每人限领一张
            baseInfo.put("get_limit", 1);
            //can_share	否 卡券领取页面是否可分享，默认为true
            baseInfo.put("can_share", true);
            //bind_openid 	否 是否指定用户领取 false
            baseInfo.put("bind_openid", false);
            //"use_custom_code" 否 是否自定义Code码 默认为false
            baseInfo.put("use_custom_code", false);
            //service_phone 否 客服电话
            if (!StringUtils.isNullStr(cardInfo.getServicePhone())) {
                baseInfo.put("service_phone", cardInfo.getServicePhone());
            }
            //"can_give_friend" 否 卡券是否可转赠,默认为true
            baseInfo.put("can_give_friend", false);
            //"location_id_list": [  否 门店位置ID 调用 POI门店管理接口 获取门店位置ID
            //    123, 12321
            //],
            //use_all_locations 否 会员卡是否支持全部门店
            baseInfo.put("use_all_locations", true);
            //"custom_url_name" 否	自定义跳转外链的入口名字。
            //"custom_url"  否 自定义跳转的URL。
            //"custom_url_sub_title" 否 显示在入口右侧的提示语。
            //"promotion_url_name" 否 营销场景的自定义入口名称。
            //"promotion_url" 否 入口跳转外链的地址链接。
            //promotion_ url_sub_title 否 显示在营销入口右侧的提示语。
            //"need_push_on_view" 否 填写true为用户点击进入会员卡时推送事件
            baseInfo.put("need_push_on_view", true);
            //center_title 否 卡券中部居中的按钮，仅在卡券激活后且可用状态 时显示
            baseInfo.put("center_title", cardInfo.getCenterTitle());
            //center_sub _title 否 显示在入口下方的提示语 ， 仅在卡券激活后且可用状态时显示
            baseInfo.put("center_sub_title", cardInfo.getCenterSubTitle());
            //center_url 否 顶部居中的url ，仅在卡券激活后且可用状态时显示
            baseInfo.put("center_url", "http://baidu.com");
            baseInfo.put("center_app_brand_pass", "pages/pay/index");
            baseInfo.put("center_app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField1 = new JSONObject();
            //name_type 否 会员信息类目半自定义名称
            //url 否 点击类目跳转外链url
            customField1.put("name", "余额");
            customField1.put("url", "http://baidu.com");
            customField1.put("app_brand_pass", "pages/user/index?redirect=pages/balance/index");
            customField1.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField2 = new JSONObject();
            customField2.put("name_type", "FIELD_NAME_TYPE_LEVEL");
            customField2.put("url", "http://baidu.com");
            customField2.put("app_brand_pass", "pages/user/index");
            customField2.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField3 = new JSONObject();
            customField3.put("name_type", "FIELD_NAME_TYPE_COUPON");
            customField3.put("url", "http://baidu.com");
            customField3.put("app_brand_pass", "pages/user/index?redirect=pages/mycoupons/index");
            customField3.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject advancedInfo = new JSONObject();
            if (!StringUtils.isNullStr(cardInfo.getTimeLimit())) {
                String[] limits = cardInfo.getTimeLimit().split("/");
                if (limits.length > 0) {
                    JSONArray timeLimit = new JSONArray();
                    for (int i = 0; i < limits.length; i++) {
                        timeLimit.put(new JSONObject().put("type", limits[i]));
                    }
                    //time_limit 否 JSON 使用时段限制
                    advancedInfo.put("time_limit", timeLimit);
                }
            }

            JSONObject memberCard = new JSONObject();
            //background_pic_url 否  商家自定义会员卡背景图
            if (!StringUtils.isNullStr(cardInfo.getBackgroundPicUrl())) {
                memberCard.put("background_pic_url", cardInfo.getBackgroundPicUrl());
            }
            //base_info 是 JSON  基本的卡券数据
            memberCard.put("base_info", baseInfo);
            //advanced_info 否 JSON
            memberCard.put("advanced_info", advancedInfo);
            //advanced_info  否 JSON 卡券高级信息
            //supply_bonus 是 显示积分
            memberCard.put("supply_bonus", false);
            //bonus_url 否 设置跳转外链查看积分详情
            //supply_balance 是	是否支持储值 --获取特殊权限
            memberCard.put("supply_balance", false);
            //balance_url 否 设置跳转外链查看余额详情
//            memberCard.put("balance_url", "");
            //prerogative 是 会员卡特权说明,限制1024汉字。
            memberCard.put("prerogative", cardInfo.getPrerogative());
            //auto_activate 否 设置为true时用户领取会员卡后系统自动将其激活，无需调用激活接口 -- 自动激活
//            memberCard.put("auto_activate",true);
            //activate_url 否 激活会员卡的url。
//            memberCard.put("activate_url", "");
            //wx_activate 否 设置为true时会员卡支持一键开卡 -- 一键开卡
            memberCard.put("wx_activate", true);
            //custom_field1 否 JSON 自定义会员信息类目，会员卡激活后显示,包含name_type (name) 和url字段
            memberCard.put("custom_field1", customField1);
            //custom_field2
            memberCard.put("custom_field2", customField2);
            //custom_field3
            memberCard.put("custom_field3", customField3);
            //custom_cell1 否 JSON 自定义会员信息类目，会员卡激活后显示。 name 入口名称。tips 入口右侧提示语，6个汉字内。 url 入口跳转链接。
            //bonus_rules 否	 积分规则。
            if (!StringUtils.isNullStr(cardInfo.getBonusRules())) {
                memberCard.put("bonus_rules", cardInfo.getBonusRules());
            }
            //bonus_rule 否	JSON 积分规则。
            //balance_rules 否 储值说明。
            //discount  否	折扣
            if (cardInfo.getDiscount() != null) {
                memberCard.put("discount", 100 - cardInfo.getDiscount());
            }
            //bonus_cleared 否 积分清零规则。
            //activate_app_brand_user_name 否 激活会原卡url对应的小程序user_name，仅可跳转该公众号绑定的小程序
            //activate_app_brand_pass 否	 激活会原卡url对应的小程序path

            JSONObject card = new JSONObject();
            card.put("card_type", "MEMBER_CARD");
            card.put("member_card", memberCard);

            JSONObject json = new JSONObject();
            json.put("card", card);

            String cardId = WXCardSignatureUtil.createCard(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
            if (!StringUtils.isNullStr(cardId)) {
                //修改商铺card_id
                shopInfo.setMembercardId(cardId);
                shopInfoMapper.updateByPrimaryKeySelective(shopInfo);
                //修改会员卡card_id
                cardInfo.setCardId(cardId);
                shopCardInfoMapper.updateByPrimaryKeySelective(cardInfo);
            }
            return cardId;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    @Override
    public boolean updateCard(Integer shopId, Integer infoId) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return false;
            }
            ShopCardInfoEntity cardInfo = shopCardInfoMapper.selectByPrimaryKey(infoId);
            if (cardInfo == null) {
                return false;
            }
            JSONObject baseInfo = new JSONObject();
            //"logo_url" 是	卡券的商户logo
            baseInfo.put("logo_url", cardInfo.getLogoUrl());
//            //"brand_name" 	是 商户名字,字数上限为12个汉字。
//            baseInfo.put("brand_name", cardInfo.getBrandName());
            //"code_type" 是 	Code展示类型
            baseInfo.put("code_type", cardInfo.getCodeType());
            //"title" 是 卡券名，字数上限为9个汉字 (建议涵盖卡券属性、服务及金额)。
            baseInfo.put("title", cardInfo.getTitle());
            //"color" 是	 	券颜色。按色彩规范标注填写Color010-Color100
            baseInfo.put("color", cardInfo.getColor());
            //"notice" 	是	卡券使用提醒，字数上限为16个汉字。
            baseInfo.put("notice", cardInfo.getNotice());
            //"description"  是 	卡券使用说明，字数上限为1024个汉字。
            baseInfo.put("description", cardInfo.getDescription());
            //"date_info": { 是	JSON	使用日期，有效期的信息。
            //    "type": "DATE_TYPE_PERMANENT" 是 使用时间的类型 支持固定时长有效类型 固定日期有效类型 永久有效类型( DATE_TYPE_PERMANENT)
            //},
            baseInfo.put("date_info", new JSONObject().put("type", "DATE_TYPE_PERMANENT"));
//            //"sku": { 	是	JSON  商品信息。
//            //    "quantity"  是		卡券库存的数量上限为100000000
//            //},
//            baseInfo.put("sku", new JSONObject().put("quantity", 80000000));
            //"get_limit" 否 每人可领券的数量限制，建议会员卡每人限领一张
            baseInfo.put("get_limit", 1);
            //can_share	否 卡券领取页面是否可分享，默认为true
            baseInfo.put("can_share", true);
//            //bind_openid 	否 是否指定用户领取 false
//            baseInfo.put("bind_openid", false);
//            //"use_custom_code" 否 是否自定义Code码 默认为false
//            baseInfo.put("use_custom_code", false);
            //service_phone 否 客服电话
            if (!StringUtils.isNullStr(cardInfo.getServicePhone())) {
                baseInfo.put("service_phone", cardInfo.getServicePhone());
            }
            //"can_give_friend" 否 卡券是否可转赠,默认为true
            baseInfo.put("can_give_friend", false);
            //"location_id_list": [  否 门店位置ID 调用 POI门店管理接口 获取门店位置ID
            //    123, 12321
            //],
            //use_all_locations 否 会员卡是否支持全部门店
            baseInfo.put("use_all_locations", true);
            //"custom_url_name" 否	自定义跳转外链的入口名字。
            //"custom_url"  否 自定义跳转的URL。
            //"custom_url_sub_title" 否 显示在入口右侧的提示语。
            //"promotion_url_name" 否 营销场景的自定义入口名称。
            //"promotion_url" 否 入口跳转外链的地址链接。
            //promotion_ url_sub_title 否 显示在营销入口右侧的提示语。
//            //"need_push_on_view" 否 填写true为用户点击进入会员卡时推送事件
//            baseInfo.put("need_push_on_view", true);
            //center_title 否 卡券中部居中的按钮，仅在卡券激活后且可用状态 时显示
            baseInfo.put("center_title", cardInfo.getCenterTitle());
            //center_sub _title 否 显示在入口下方的提示语 ， 仅在卡券激活后且可用状态时显示
            baseInfo.put("center_sub_title", cardInfo.getCenterSubTitle());
            //center_url 否 顶部居中的url ，仅在卡券激活后且可用状态时显示
            baseInfo.put("center_url", "http://baidu.com");
            baseInfo.put("center_app_brand_pass", "pages/pay/index");
            baseInfo.put("center_app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField1 = new JSONObject();
            //name_type 否 会员信息类目半自定义名称
            //url 否 点击类目跳转外链url
            customField1.put("name", "余额");
            customField1.put("url", "http://baidu.com");
            customField1.put("app_brand_pass", "pages/user/index?redirect=pages/balance/index");
            customField1.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField2 = new JSONObject();
            customField2.put("name_type", "FIELD_NAME_TYPE_LEVEL");
            customField2.put("url", "http://baidu.com");
            customField2.put("app_brand_pass", "pages/user/index");
            customField2.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject customField3 = new JSONObject();
            customField3.put("name_type", "FIELD_NAME_TYPE_COUPON");
            customField3.put("url", "http://baidu.com");
            customField3.put("app_brand_pass", "pages/user/index?redirect=pages/mycoupons/index");
            customField3.put("app_brand_user_name", shopInfo.getAppGhId() + "@app");

            JSONObject advancedInfo = new JSONObject();
            if (!StringUtils.isNullStr(cardInfo.getTimeLimit())) {
                String[] limits = cardInfo.getTimeLimit().split("/");
                if (limits.length > 0) {
                    JSONArray timeLimit = new JSONArray();
                    for (int i = 0; i < limits.length; i++) {
                        timeLimit.put(new JSONObject().put("type", limits[i]));
                    }
                    //time_limit 否 JSON 使用时段限制
                    advancedInfo.put("time_limit", timeLimit);
                }
            }

            JSONObject memberCard = new JSONObject();
            //background_pic_url 否  商家自定义会员卡背景图
            if (!StringUtils.isNullStr(cardInfo.getBackgroundPicUrl())) {
                memberCard.put("background_pic_url", cardInfo.getBackgroundPicUrl());
            }
            //base_info 是 JSON  基本的卡券数据
            memberCard.put("base_info", baseInfo);
            //advanced_info 否 JSON 卡券高级信息
            memberCard.put("advanced_info", advancedInfo);
            //supply_bonus 是 显示积分
            memberCard.put("supply_bonus", false);
            //bonus_url 否 设置跳转外链查看积分详情
            //supply_balance 是	是否支持储值 --获取特殊权限
            memberCard.put("supply_balance", false);
            //balance_url 否 设置跳转外链查看余额详情
//            memberCard.put("balance_url", "");
            //prerogative 是 会员卡特权说明,限制1024汉字。
            memberCard.put("prerogative", cardInfo.getPrerogative());
            //auto_activate 否 设置为true时用户领取会员卡后系统自动将其激活，无需调用激活接口 -- 自动激活
//            memberCard.put("auto_activate",true);
            //activate_url 否 激活会员卡的url。
//            memberCard.put("activate_url", "");
            //wx_activate 否 设置为true时会员卡支持一键开卡 -- 一键开卡
            memberCard.put("wx_activate", true);
            //custom_field1 否 JSON 自定义会员信息类目，会员卡激活后显示,包含name_type (name) 和url字段
            memberCard.put("custom_field1", customField1);
            //custom_field2
            memberCard.put("custom_field2", customField2);
            //custom_field3
            memberCard.put("custom_field3", customField3);
            //custom_cell1 否 JSON 自定义会员信息类目，会员卡激活后显示。 name 入口名称。tips 入口右侧提示语，6个汉字内。 url 入口跳转链接。
            //bonus_rules 否	 积分规则。
            if (!StringUtils.isNullStr(cardInfo.getBonusRules())) {
                memberCard.put("bonus_rules", cardInfo.getBonusRules());
            }
            //bonus_rule 否	JSON 积分规则。
            //balance_rules 否 储值说明。
            //discount  否	折扣
            memberCard.put("discount", 100 - (cardInfo.getDiscount() == null ? 100 : cardInfo.getDiscount()));

            //bonus_cleared 否 积分清零规则。
            //activate_app_brand_user_name 否 激活会原卡url对应的小程序user_name，仅可跳转该公众号绑定的小程序
            //activate_app_brand_pass 否	 激活会原卡url对应的小程序path

            JSONObject card = new JSONObject();
            card.put("card_id", cardInfo.getCardId());
            card.put("member_card", memberCard);

            JSONObject json = new JSONObject();
            json.put("card", card);
            return WXCardSignatureUtil.updateCard(shopInfo.getWechatId(), shopInfo.getWechatSecret(), card.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean setCard(Integer shopId, Integer infoId) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return false;
            }
            ShopCardInfoEntity cardInfo = shopCardInfoMapper.selectByPrimaryKey(infoId);
            if (cardInfo == null) {
                return false;
            }

            JSONObject json = new JSONObject();
            json.put("card_id", shopInfo.getMembercardId());

            //必填项 选项类型
            if (!StringUtils.isNullStr(cardInfo.getRequiredForm())) {
                JSONArray requiredArray = new JSONArray();
                String[] requiredForms = cardInfo.getRequiredForm().split("/");
                if (requiredForms.length > 0) {
                    for (int i = 0; i < requiredForms.length; i++) {
                        requiredArray.put(requiredForms[i]);
                    }
                }
                //必填项
                JSONObject requiredForm = new JSONObject();
                requiredForm.put("can_modify", false);
                requiredForm.put("common_field_id_list", requiredArray);

                json.put("required_form", requiredForm);
            }

            //选填项 选项类型
            if (!StringUtils.isNullStr(cardInfo.getOptionalForm())) {
                JSONArray optionalArray = new JSONArray();
                String[] optionalForms = cardInfo.getOptionalForm().split("/");
                if (optionalForms.length > 0) {
                    for (int i = 0; i < optionalForms.length; i++) {
                        optionalArray.put(optionalForms[i]);
                    }
                }
                //选填项
                JSONObject optionalForm = new JSONObject();
                optionalForm.put("can_modify", false);
                optionalForm.put("common_field_id_list", optionalArray);

                json.put("optional_form", optionalForm);
            }

            return WXCardSignatureUtil.setCard(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    @Override
    public com.alibaba.fastjson.JSONObject getUserinfoByCard(Integer userId, Integer shopId) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return null;
            }
            UserEntity user = userService.wechatPayGetUser(userId);
            if (user == null || StringUtils.isNullStr(user.getWxCard())) {
                return null;
            }

            JSONObject json = new JSONObject();
            json.put("card_id", shopInfo.getMembercardId());
            json.put("code", user.getWxCard());

            return WXCardSignatureUtil.getUserinfoByCard(shopInfo.getWechatId(), shopInfo.getWechatSecret(), json.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    @Override
    public com.alibaba.fastjson.JSONObject activateCard(Integer shopId) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null || StringUtils.isNullStr(shopInfo.getMembercardId())) {
                return null;
            }

            JSONObject json = new JSONObject();
            json.put("card_id", shopInfo.getMembercardId());
            json.put("outer_str", shopId);

            com.alibaba.fastjson.JSONObject reJson = WXCardSignatureUtil.activateCard(shopInfo.getWechatId(), shopInfo.getWechatSecret(),
                    json.toString());
            //保存开卡组件信息
            shopInfo.setWechatEncryptCardId(reJson.getString("encrypt_card_id"));
            shopInfo.setWechatBiz(reJson.getString("biz"));
            shopInfoMapper.updateByPrimaryKeySelective(shopInfo);
            return reJson;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    @Override
    public String uploadImg(Integer shopId, MultipartFile file) throws Exception {
        try {
            ShopInfoEntity shopInfo = shopService.wechatGetShopInfo(shopId);
            if (shopInfo == null) {
                return null;
            }
            return WXCardSignatureUtil.uploadImg(shopInfo.getWechatId(), shopInfo.getWechatSecret(), file);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw e;
        }
    }

    @Override
    public boolean getUnlimited(Integer shopId, Integer userId, String path, String page) {
        try {
            ShopInfoEntity shopInfo = shopService.wechatPayGetShopInfo(shopId);
            if (shopInfo == null) {
                return false;
            }

            JSONObject json = new JSONObject();
            if (userId != null) {
                json.put("scene", userId.toString());
//                json.put("scene", "parentId="+userId+"&shopId="+shopId);
            }
            json.put("page", page);
            json.put("width", 280);
            File file = new File(path);
            if (file.exists()) {
                return true;
            }
            return WXCardSignatureUtil.getUnlimited(shopInfo.getAppId(), shopInfo.getAppSecret(), json.toString(), path);
        } catch (ApiException e) {
            throw e;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    @Override
    public List<MpIndexPageEntity> getAllMpIndexPage() {
        return mpIndexPageMapper.selectAll();
    }


    private boolean pushMpMessage(ShopInfoEntity shopInfo, String params) {
        try {

            boolean result = WXCardSignatureUtil.xcxTemplateSend(shopInfo.getAppId(), shopInfo.getAppSecret(), params);
            if (result) {
                MpMessageLogEntity mpMessageLogEntity = new MpMessageLogEntity();
                mpMessageLogEntity.setLog(params);
                mpMessageLogMapper.insert(mpMessageLogEntity);
            }
            return result;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    private String getBalanceChangeNotifyTemplateId(ShopInfoEntity shopInfo, String templateCode) {
        try {
            String mpTemplateId = shopInfo.getPayTemplateId();
            if (StringUtils.isNotBlank(mpTemplateId)) {
                return mpTemplateId;
            }

            //{"errcode":0,"errmsg":"ok","id":"AT0157","title":"账户余额提醒","keyword_list":[{"keyword_id":1,"name":"开户时间",
            // "example":"2017-1-11 16:56:19"},{"keyword_id":2,"name":"开户银行","example":"微众银行"},{"keyword_id":3,"name":"开户卡号",
            // "example":"6222********3232"},{"keyword_id":4,"name":"账户余额","example":"0.00元"},{"keyword_id":5,"name":"账户功能",
            // "example":"智能存款服务、定期存款服务"},{"keyword_id":6,"name":"当前余额","example":"200.00"},{"keyword_id":7,"name":"变动金额","example":"-19
            // .00"},{"keyword_id":8,"name":"变动时间","example":"2016-03-25 09:36"},{"keyword_id":9,"name":"变动类型",
            // "example":"充值\/消费\/礼品卡兑换"},{"keyword_id":10,"name":"账户名称","example":"咔酷咔"},{"keyword_id":11,"name":"消费店铺",
            // "example":"郑州市河东店"},{"keyword_id":12,"name":"温馨提示","example":"账户内有余额，别忘了提现"},{"keyword_id":13,"name":"变动原因",
            // "example":"消费支出"},{"keyword_id":14,"name":"商户名称","example":"每日优鲜会员店"},{"keyword_id":15,"name":"会员卡类型","example":"优惠卡"},
            // {"keyword_id":16,"name":"订单号","example":"123456789"},{"keyword_id":17,"name":"会员昵称","example":"张三"},{"keyword_id":18,
            // "name":"商家名称","example":"鲜老虎"},{"keyword_id":19,"name":"冻结余额","example":"88.00"},{"keyword_id":20,"name":"解冻时间",
            // "example":"2018-10-1 00:00:00"},{"keyword_id":21,"name":"公交卡号","example":"8344100055"},{"keyword_id":22,"name":"总消费金额",
            // "example":"1000"},{"keyword_id":23,"name":"商品价格","example":"860"},{"keyword_id":24,"name":"跑腿费","example":"140"},
            // {"keyword_id":25,"name":"總消費金額","example":"MOP:140"},{"keyword_id":26,"name":"商品價格","example":"MOP:100"},{"keyword_id":27,
            // "name":"車手費用","example":"1公里花費MOP:40"},{"keyword_id":28,"name":"賬號餘額","example":"MOP:10"},{"keyword_id":29,"name":"消费金额",
            // "example":"32.5 元"},{"keyword_id":30,"name":"消费时间","example":"2019-4-2 15:42:09"},{"keyword_id":31,"name":"到期时间",
            // "example":"2019-06-01 24:00:00"},{"keyword_id":32,"name":"商品名称","example":"沃尔玛代金券"}]}
            com.alibaba.fastjson.JSONArray keywords = new com.alibaba.fastjson.JSONArray();
            keywords.add(6);
            keywords.add(7);
            keywords.add(8);
            keywords.add(13);
            mpTemplateId = ComponentUtil.serviceTemplate(shopInfo.getAppId(), templateCode, keywords);
            shopInfo.setPayTemplateId(mpTemplateId);
            shopService.updateShopInfo(shopInfo);
            return mpTemplateId;
        } catch (Exception e) {
            log.error("get mp template id error: {}", e.getMessage(), e);
            throw new ApiException(ErrorCodeEnum.WP8009);
        }
    }

    private String getMpMessageTemplateId(ShopInfoEntity shopInfo, String templateCode) {
        try {
            String mpTemplateId = shopInfo.getMessageTemplateId();
            if (StringUtils.isNotBlank(mpTemplateId)) {
                return mpTemplateId;
            }
            //{"errcode":0,"errmsg":"ok","id":"AT0480","title":"网络信息到达提醒","keyword_list":[{"keyword_id":1,"name":"信息编号",
            // "example":"2589645"},{"keyword_id":3,"name":"信息来源","example":"在线咨询"},{"keyword_id":4,"name":"所在地区","example":"广东省广州市"},
            // {"keyword_id":5,"name":"分配时间","example":"2017-06-12 14:38:23"},{"keyword_id":6,"name":"用户昵称","example":"lixiaolong"},
            // {"keyword_id":9,"name":"查看方式","example":"点击微信的发现-小程序"},{"keyword_id":11,"name":"信息内容","example":"您的预定已成功"},
            // {"keyword_id":12,"name":"通知时间","example":"通知时间"},{"keyword_id":13,"name":"发送时间","example":"2019-07-08 12:30"}]}
            //String result = ComponentUtil.getTemplate(shopInfo.getAppId(), templateCode);
            //com.alibaba.fastjson.JSONObject object = JSON.parseObject(result);
            //com.alibaba.fastjson.JSONArray keywordList = object.getJSONArray("keyword_list");
            //com.alibaba.fastjson.JSONArray keywords = new com.alibaba.fastjson.JSONArray();
            //for (int i = 0; i < keywordList.size(); i++) {
            //    com.alibaba.fastjson.JSONObject jsonObject = keywordList.getJSONObject(i);
            //    keywords.add(jsonObject.getInteger("keyword_id"));
            //}

            com.alibaba.fastjson.JSONArray keywords = new com.alibaba.fastjson.JSONArray();
            keywords.add(13);
            keywords.add(11);
            mpTemplateId = ComponentUtil.serviceTemplate(shopInfo.getAppId(), templateCode, keywords);
            shopInfo.setMessageTemplateId(mpTemplateId);
            shopService.updateShopInfo(shopInfo);
            return mpTemplateId;
        } catch (Exception e) {
            log.error("get mp template id error: {}", e.getMessage(), e);
            throw new ApiException(ErrorCodeEnum.WP8009);
        }
    }

    private String getCouponsNotifyTemplateId(ShopInfoEntity shopInfo, String templateCode) {
        try {
            String mpTemplateId = shopInfo.getCouponsTemplateId();
            if (StringUtils.isNotBlank(mpTemplateId)) {
                return mpTemplateId;
            }
            // {"errcode":0,"errmsg":"ok","id":"AT0551","title":"领取成功通知","keyword_list":[{"keyword_id":1,"name":"姓名","example":"陈大大"},
            // {"keyword_id":2,"name":"电话","example":"136XXXXXXXX"},{"keyword_id":4,"name":"有效期","example":"2017\/6\/30"},
            // {"keyword_id":6,"name":"订单号码","example":"1234567890"},{"keyword_id":7,"name":"商户名称","example":"某某某时尚美发工作室"},
            // {"keyword_id":8,"name":"商户地址","example":"黑龙江省大庆市龙分区卧龙路764号"},{"keyword_id":9,"name":"商户电话","example":"0459-6666666"},
            // {"keyword_id":14,"name":"失效日期","example":"2017-08-01"},{"keyword_id":19,"name":"商品分类","example":"饮料"},{"keyword_id":20,
            // "name":"领取时间","example":"2017.06.30 15:00"},{"keyword_id":21,"name":"设备编码","example":"ZY-0001-12"},{"keyword_id":22,
            // "name":"设备地址","example":"北京市海淀区"},{"keyword_id":23,"name":"领取数量","example":"1"},{"keyword_id":24,"name":"领取单号",
            // "example":"120202123"},{"keyword_id":25,"name":"适用范围","example":"可在摩拜单车小程序中支付车费、充值、购买月卡"},{"keyword_id":26,"name":"微信号",
            // "example":"weixin"},{"keyword_id":27,"name":"领取金额","example":"10元"},{"keyword_id":29,"name":"领取赏金","example":"10元"},
            // {"keyword_id":30,"name":"领取人","example":"开心的笨小孩"},{"keyword_id":31,"name":"发起人","example":"琴弦泪"},{"keyword_id":32,
            // "name":"店铺名称","example":"时尚美发工作室"},{"keyword_id":33,"name":"会员卡号","example":"炫酷计时卡"},{"keyword_id":38,"name":"奖品名称",
            // "example":"60元红包"},{"keyword_id":39,"name":"兑换时间","example":"20180320-20180328"},{"keyword_id":40,"name":"赠送人",
            // "example":"张三"},{"keyword_id":41,"name":"票种类型","example":"嘉宾票"},{"keyword_id":42,"name":"设备信息",
            // "example":"您的xxxx-xxx设备已通过审核"},{"keyword_id":43,"name":"课程名称","example":"拥抱精益创新思维"},{"keyword_id":44,"name":"保险名称",
            // "example":"意外险"},{"keyword_id":46,"name":"家长姓名","example":"请填写"},{"keyword_id":47,"name":"家长手机","example":"请填写"},
            // {"keyword_id":48,"name":"宝宝生日","example":"请填写"},{"keyword_id":49,"name":"商家品牌","example":"请填写"},{"keyword_id":50,
            // "name":"商家地址","example":"请填写"},{"keyword_id":51,"name":"身份信息","example":"330211********0000"},{"keyword_id":52,
            // "name":"门店名称","example":"门店一"},{"keyword_id":53,"name":"发车时间","example":"2018-11-11 08:00"},{"keyword_id":54,
            // "name":"所属会员卡","example":"八合里海记会员卡（普通会员）"},{"keyword_id":55,"name":"运单号","example":"123456789"},{"keyword_id":56,
            // "name":"快递公司","example":"顺丰"},{"keyword_id":57,"name":"时间","example":"2019.5.16"},{"keyword_id":58,"name":"收货地址",
            // "example":"北京市海淀区东升科技园A"},{"keyword_id":59,"name":"物品名称","example":"物品"},{"keyword_id":60,"name":"使用说明",
            // "example":"满3000元可以使用"},{"keyword_id":61,"name":"商品名称","example":"可乐330ml听装"}]}

            com.alibaba.fastjson.JSONArray keywords = new com.alibaba.fastjson.JSONArray();
            keywords.add(61);
            keywords.add(20);
            keywords.add(4);
            mpTemplateId = ComponentUtil.serviceTemplate(shopInfo.getAppId(), templateCode, keywords);
            shopInfo.setCouponsTemplateId(mpTemplateId);
            shopService.updateShopInfo(shopInfo);
            return mpTemplateId;
        } catch (Exception e) {
            log.error("get mp template id error: {}", e.getMessage(), e);
            throw new ApiException(ErrorCodeEnum.WP8009);
        }
    }

}
